#include "StretchOperationWidget.h"

#include "Core/MainWindow.h"
#include <QMessageBox>
#include <BRepPrimAPI_MakePrism.hxx>
#include "FeatureShape/HistoryManager.h"
#include "FeatureShape/FeatureShape.h"
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
#include "QFillOperationWidget.h"

StretchOperationWidget::StretchOperationWidget(MainWindow* inMainWindow, ShapeOperation* inOperation, QWidget* parent)
	: QRSWidgetBase(inMainWindow, inOperation, parent)
	, ui(new Ui::StretchOperationWidgetClass())
{
	ui->setupUi(this);
	ui->confirmButton->setEnabled(false);

	ui->targetWidget->installEventFilter(this);
	ui->dirWidget->installEventFilter(this);

	ui->targetWidget->setStyleSheet("background-color:rgb(255,178,102)");

	QPixmap tempErrorImg = QPixmap(".//Resource//error.png");
	ui->targetImg->setPixmap(tempErrorImg);
	ui->targetImg->setMaximumSize(QSize(20, 20));
	ui->targetImg->setScaledContents(true);

	connect(ui->modifyButton, &QPushButton::clicked, this, &StretchOperationWidget::OnModify);
	connect(ui->confirmButton, &QPushButton::clicked, this, &StretchOperationWidget::OnConfirm);
	connect(ui->cancelButton, &QPushButton::clicked, this, &StretchOperationWidget::close);

	connect(m_mainWindow, &MainWindow::OnSelectedSubShapes, this, &StretchOperationWidget::OnSelectedSubShapes);

	connect(ui->targetCombo, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &StretchOperationWidget::OnTargetComboIndexChange);

	m_dir = new RWTripleFloatInput(ui->dirX, ui->dirY, ui->dirZ);

	m_mainWindow->SetSelectionMode(SM_Face);
}

StretchOperationWidget::~StretchOperationWidget()
{
	delete ui;
	delete m_dir;
}

void StretchOperationWidget::OnSelectedSubShapes(QIVtkSelectionPipeline* actor)
{
	// 已经修改过了
	if (!ui->modifyButton->isEnabled())
	{
		return;
	}

	// 选择操作对象
	if (focusIndex == 0)
	{
		m_shapelist = m_mainWindow->GetSelectedShapes();
		m_selectedActor = actor;

		// 清除
		while (selectTempActor.size())
		{
			m_mainWindow->RemoveTempActor(selectTempActor.back());
			selectTempActor.pop_back();
		}
		// 增加新的
		for (int i = 0; i < m_shapelist.size(); i++)
		{
			selectTempActor.push_back(m_mainWindow->CreateTempActor(m_shapelist[i]));
		}

		if (m_shapelist.size())
		{
			QPixmap tempOKImg = QPixmap(".//Resource//right.png");
			ui->targetImg->setPixmap(tempOKImg);
		}
	}
	// 选择方向
	else if (focusIndex == 1 && m_mainWindow->GetSelectedShapes().size())
	{
		const TopoDS_Shape& selectedShape = m_mainWindow->GetSelectedShapes().back();
		// 选取的不是边
		if (selectedShape.ShapeType() != TopAbs_EDGE)
		{
			return;
		}
		TopoDS_Edge selectedEdge = TopoDS::Edge(selectedShape);
		gp_Dir edgeDirection = GetEdgeDirection(selectedEdge);
		m_dir->SetValue(edgeDirection);
	}
}

void StretchOperationWidget::closeEvent(QCloseEvent* event)
{
	disconnect(m_mainWindow, &MainWindow::OnSelectedSubShapes, this, &StretchOperationWidget::OnSelectedSubShapes);

	if (!bIsConfirmed)
	{
		if (cacheActor)
		{
			m_mainWindow->RemoveActorFromRenderer(cacheActor);
			//std::cout << "StretchOperationWidget::closeEvent, remove cacheActor" << std::endl;
			cacheActor = nullptr;
		}
	}

	// 清除
	while (selectTempActor.size())
	{
		m_mainWindow->RemoveTempActor(selectTempActor.back());
		selectTempActor.pop_back();
	}

	m_mainWindow->SubWidgetClose(bIsConfirmed);
}

bool StretchOperationWidget::eventFilter(QObject* obj, QEvent* event)
{
	QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
	if (event->type() == QEvent::MouseButtonPress && mouseEvent->button() == Qt::LeftButton)
	{
		if (obj == ui->targetWidget && focusIndex != 0)
		{
			ui->targetWidget->setStyleSheet("background-color:rgb(255,178,102)");
			ui->dirWidget->setStyleSheet("background-color: #FFFFFF;");

			focusIndex = 0;
			OnTargetComboIndexChange(ui->targetCombo->currentIndex());
			m_mainWindow->SetCanMultiSelect(true);
		}
		if (obj == ui->dirWidget && focusIndex != 1)
		{
			ui->dirWidget->setStyleSheet("background-color:rgb(255,178,102)");
			ui->targetWidget->setStyleSheet("background-color: #FFFFFF;");

			focusIndex = 1;
			m_mainWindow->SetSelectionMode(SM_Edge);
			m_mainWindow->SetCanMultiSelect(false);
		}
	}

	return QObject::eventFilter(obj, event);
}

void StretchOperationWidget::OnModify()
{
	if (m_shapelist.empty())
	{
		QMessageBox::warning(this, "警告", "没有选择拉伸对象");
		return;
	}

	if ((IsNearlyZero(ui->dirX->value()) && IsNearlyZero(ui->dirY->value()) && IsNearlyZero(ui->dirZ->value())) || IsNearlyZero(ui->len->value()))
	{
		 QMessageBox::warning(this, "警告", "请输入有效的拉伸方向和拉伸长度");
		 return;
	}

	stretchVector = gp_Vec(ui->dirX->value(), ui->dirY->value(), ui->dirZ->value()) * ui->len->value();

	// 尝试将选择的边转化为face
	TopoDS_Face face;
	if(m_shapelist[0].get().ShapeType() == TopAbs_EDGE)
	{
		std::vector<TopoDS_Edge> selectEdges;
		for (int i = 0; i < m_shapelist.size(); i++)
		{
			if (m_shapelist[i].get().ShapeType() == TopAbs_EDGE)
			{
				selectEdges.push_back(TopoDS::Edge(m_shapelist[i]));
			}
		}
		std::vector<TopoDS_Wire> wires = QFillOperationWidget::BuildWiresFromEdges(selectEdges);
		if (wires.size())
		{
			face = QFillOperationWidget::CreateFaceWithHoles(wires);
		}
	}
	TopoDS_Shape resultShape;
	if (face.IsNull())
	{
		BRepPrimAPI_MakePrism prismShape(m_shapelist[0], stretchVector);
		resultShape = prismShape.Shape();

		for (int i = 1; i < m_shapelist.size(); i++)
		{
			BRepPrimAPI_MakePrism tempPrismShape(m_shapelist[i], stretchVector);
			resultShape = m_mainWindow->BooleanOperation(resultShape, tempPrismShape, BooleanOP::Union);
		}
	}
	else
	{
		BRepPrimAPI_MakePrism prismShape(face, stretchVector);
		resultShape = prismShape.Shape();
	}

	if (resultShape.IsNull())
	{
		QMessageBox::warning(this, "警告", "拉伸失败");
		return;
	}

	cacheActor = m_mainWindow->createBasicUnitActor(resultShape);
	ui->confirmButton->setEnabled(true);
	ui->modifyButton->setEnabled(false);

	bUseEdge = ui->targetCombo->currentIndex() == 1;
}

void StretchOperationWidget::OnConfirm()
{
	bIsConfirmed = true;

	int selectedActorIndex = GetIndexFromActor(m_mainWindow->GetCachedActors(), m_selectedActor);
	std::vector<int> subShapeIndex;
	TopAbs_ShapeEnum shapeType = bUseEdge ? TopAbs_EDGE : TopAbs_FACE;
	int i = 0;
	TopExp_Explorer explorer(m_selectedActor->OccShape(), shapeType);
	while (explorer.More())
	{
		bool bFind = std::find_if(m_shapelist.begin(), m_shapelist.end(),
			[&explorer](std::reference_wrapper<const TopoDS_Shape> shape)
			{
				return shape.get().IsEqual(explorer.Current());
			}) != m_shapelist.end();
		if (bFind)
		{
			subShapeIndex.push_back(i);
		}
		explorer.Next();
		i++;
	}

	if (cacheActor)
	{
		m_mainWindow->OnActorConfirmCreate(cacheActor);
		cacheActor->m_featureShape.reset(new FeatureShapeMix(cacheActor->OccShape()));
	}
	// #FIX: 选择的对象分属于不同的actor，会有多个selectedActorIndex，涉及到可以多选的 op 可能都有这个问题
	StretchOperation* op = new StretchOperation("拉伸运算", selectedActorIndex, subShapeIndex, stretchVector, bUseEdge);
	m_mainWindow->GetHistoryManager()->applyOperation(op);

	close();
}

void StretchOperationWidget::OnTargetComboIndexChange(int index)
{
	if (index == 0)
	{
		m_mainWindow->SetSelectionMode(SM_Face);
	}
	else if (index == 1)
	{
		m_mainWindow->SetSelectionMode(SM_Edge);
	}
}
